package at.syncme.aspects.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.Vector;

import at.syncme.framework.Game;



/**
 * server aspect of a client server architecture
 * 
 * @author Daniel Rudigier
 */
public aspect TCPServerAspect {
    private static final int NW_PORT = 4711;

    private boolean running;

    protected Game game;

    protected List out;

    pointcut GameStart(): call (at.syncme.framework.Game+.new());

    /**
     * init the server socket
     */
    after() returning (Game g): GameStart() {
        this.game = g;
        this.running = true;
        this.out = new Vector();

        // run the server thread
        new Thread(new Runnable() {
            public void run() {
                try {
                    ServerSocket ss = new ServerSocket(NW_PORT);
                    System.out.println("listening on port: " + NW_PORT);

                    while (running) {
                        Socket s = ss.accept();

                        System.out.println("connection accepted");
                        out.add(new OutputStreamWriter(s.getOutputStream()));
                        new Thread(new Worker(s)).start();
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }

        }).start();
    }

    /**
     * handle incoming requests
     */
    private class Worker implements Runnable {
        private Socket socket;

        private BufferedReader is;

        private int clientId;

        /**
         * constructor
         * 
         * @param s
         *            socket
         */
        public Worker(Socket s) {
            this.socket = s;
            this.clientId = this.hashCode();

            try {
                this.is = new BufferedReader(new InputStreamReader(s
                        .getInputStream()));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        public void run() {
            // game.gameEvent(clientId, null); // new client connected

            String line = null;
            try {
                while ((line = is.readLine()) != null) {
//                    processMessage(clientId, line);
                }
                this.socket.close();
            } catch (IOException e) {
                // client behaves strangely
                if (!checkAlive()) {
//                    Event e = Event.create(Event.PLAYER_DISCONNECTED,
//                            Event.PRIORITY_HIGH);
//                    game.gameEvent(e);
                }
                e.printStackTrace();
            }
        }

        /**
         * check if the connection is alive
         * 
         * @return
         */
        private boolean checkAlive() {
            return false;
        }

    }

}
